若有在 Aure 透過虛擬機器來架設服務的朋友,應該都會在網路安全性群組限制僅有特定 IP 才能夠進行存取,避免服務遭受惡意攻擊。
如果我們的服務需要開放特定地理區域,例如只有台灣能夠存取。
此時網路安全性群組就幫不上忙了
我們根據 db-ip.com 提供的免費資料庫
https://download.db-ip.com/free/dbip-country-lite-2023-04.csv.gz
台灣 IPv4 與 IPv6 Ranges 加起來就至少 2,000 條規則
1337 IPv4 ranges for TW
673 IPv6 ranges for TW
我們把頭撇向隔壁的大哥 Azure 防火牆
光是部署的費用每個月就要花快三萬,還不包含處理的資料量。
我還是捏懶趴自殺好了。
今天我們就來教大家如何在 Ubuntu 20.04 透過防火牆對 GeoIP 進行封鎖
先決條件
sudo apt update
sudo apt-get install curl unzip perl
sudo apt-get install xtables-addons-common
sudo apt-get install libtext-csv-xs-perl libmoosex-types-netaddr-ip-perl
下載資料庫
建立資料夾以存放資料庫數據
sudo mkdir /usr/share/xt_geoip
新增一個腳本
sudo vi /usr/local/bin/update-geoip.sh
內容如下
#!/bin/bash
# Create temporary directory
mkdir -p /usr/share/xt_geoip/tmp/
# Download the geoip database file
cd /usr/share/xt_geoip/tmp/
/usr/lib/xtables-addons/xt_geoip_dl
# Update geoip xtables
/usr/bin/perl /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip/ -S /usr/share/xt_geoip/tmp
# Remove temp directory
rm -r /usr/share/xt_geoip/tmp/
賦予執行權限並運行腳本
sudo chmod +x /usr/local/bin/update-geoip.sh
sudo /usr/local/bin/update-geoip.sh
下載 GeoIP 數據填充資料庫以供使用
--2023-04-19 05:50:45-- https://download.db-ip.com/free/dbip-country-lite-2023-04.csv.gz
Resolving download.db-ip.com (download.db-ip.com)... 172.67.75.166, 104.26.4.15, 104.26.5.15
Connecting to download.db-ip.com (download.db-ip.com)|172.67.75.166|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3674555 (3.5M) [application/octet-stream]
Saving to: 'dbip-country-lite.csv.gz'
dbip-country-lite.csv.gz 100%[==========================>] 3.50M --.-KB/s in 0.02s
2023-04-19 05:50:45 (141 MB/s) - 'dbip-country-lite.csv.gz' saved [3674555/3674555]
588141 entries total
70 IPv4 ranges for AD
54 IPv6 ranges for AD
670 IPv4 ranges for AE
390 IPv6 ranges for AE
...(略)...
123 IPv4 ranges for ZW
55 IPv6 ranges for ZW
14 IPv4 ranges for ZZ
3 IPv6 ranges for ZZ
設定排程定期更新資料庫
sudo crontab -e
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
30 8 * * * /usr/local/bin/update-geoip.sh >> /var/log/update-geoip.log 2>&1
配置防火牆
先看一下目前的防火牆設定,很好非常乾淨。
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
可以透過下列指令將 iptables 清除乾淨
sudo iptables -F
或
sudo iptables --flush
sudo iptables --delete-chain
先禁止所有的 HTTP 與 HTTPS 進入
sudo iptables -A INPUT -p tcp --destination-port 80 -j DROP
sudo iptables -A INPUT -p tcp --destination-port 443 -j DROP
開放只有台灣可以存取 HTTP 與 HTTPS
sudo iptables -I INPUT -p tcp -m geoip --source-country TW --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m geoip --source-country TW --dport 443 -j ACCEPT
調整完的防火牆設定如下
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere -m geoip --source-country TW tcp dpt:https
ACCEPT tcp -- anywhere anywhere -m geoip --source-country TW tcp dpt:http
DROP tcp -- anywhere anywhere tcp dpt:http
DROP tcp -- anywhere anywhere tcp dpt:https
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
注意 ACCEPT 的規則需要再 DROP 之前才有效果喔
儲存設定
上面新增的防火牆規則,其實只要重開機就會消失了。
想要把設定永久保留下來,則需要透過 iptables-save 與 iptables-restore 這兩個指令來完成。
sudo iptables-save
# Generated by iptables-save v1.8.4 on Wed Apr 19 16:14:49 2023
*filter
:INPUT ACCEPT [5549:1254010]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [7857:1910189]
-A INPUT -p tcp -m geoip --source-country TW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m geoip --source-country TW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j DROP
-A INPUT -p tcp -m tcp --dport 443 -j DROP
COMMIT
# Completed on Wed Apr 19 16:14:49 2023
# Generated by iptables-save v1.8.4 on Wed Apr 19 16:14:49 2023
*security
:INPUT ACCEPT [5389:1457894]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [740:128604]
-A OUTPUT -d 168.63.129.16/32 -p tcp -m tcp --dport 53 -j ACCEPT
-A OUTPUT -d 168.63.129.16/32 -p tcp -m owner --uid-owner 0 -j ACCEPT
-A OUTPUT -d 168.63.129.16/32 -p tcp -m conntrack --ctstate INVALID,NEW -j DROP
COMMIT
# Completed on Wed Apr 19 16:14:49 2023
先將 iptables-save 指令的輸出結果儲存到特定檔案
sudo iptables-save > iptables.conf
再將組態檔案透過 iptables-restore 指令進行匯入
sudo iptables-restore < iptables.conf
還需設定開機時執行 iptables-restore 指令,才能永久保存設定。
這樣真的太麻煩了,所以後來出了 iptables-persistent 套件,就不需要手動使用 iptables-save 相關指令。
sudo apt install iptables-persistent
在安裝的時候會詢問是否要儲存目前 iptables 和 ipv6tables 的畫面
開機時就會自動使用 iptables-restore 和 ip6tables-restore 指令來套用 /etc/iptables/rules.v4 和 /etc/iptables/rules.v6 的設定。
之後每次修改完 iptables 只要執行以下指令即可
sudo dpkg-reconfigure iptables-persistent
記得到網路安全性群組把 HTTP 與 HTTPS 的封印解開
根據筆者的經驗只開放台灣的 IP 存取服務,基本上就可以擋掉 95% 以上的網路攻擊。
如果我們在 Azure 開立一台 Apache 反向代理伺服器並啟用下列模組
再搭配防火牆對 GeoIP 進行封鎖,不就是一台小型的 DoorFront 伺服器囉。
若您使用 Ubuntu 18.04 的話,可以參考這篇文章
參考文件